package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"math/rand"
	"net/http"
	"time"
)

func TimeCost() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()
		randomSleepTime := rand.Intn(401) + 100

		fmt.Printf("sleep %d ms\n", randomSleepTime)
		time.Sleep(time.Millisecond * time.Duration(randomSleepTime))
		fmt.Printf("sleep end\n")
		c.Next()
		end := time.Now()
		cost := end.Sub(start)
		fmt.Printf("time cost: %v\n", cost)
	}
}

func AuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		fmt.Println("auth middleware enter ")
		// 这里是中间件逻辑
		token := c.GetHeader("Authorization")
		if token == "" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "token is empty"})
		}
		if token != "123456" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "token is invalid"})
		}

		userInfo := map[string]interface{}{
			"username": "leo",
			"role":     "admin",
		}
		c.Set("user", userInfo)
		c.Next()
	}

}

func GetUserFromContext(c *gin.Context) (map[string]interface{}, error) {
	user, exists := c.Get("user")
	if !exists {
		return nil, fmt.Errorf("user not exists")
	}
	userInfo := user.(map[string]interface{})
	return userInfo, nil
}

// (2) LoggingMiddleware：记录请求信息（包括用户信息）
func LoggingMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		user, exists := c.Get("user")
		if !exists {
			fmt.Println("user not exists")
			user = "unknown user"
		}
		fmt.Printf("%s %s %s\n", c.ClientIP(), c.Request.Method, user)
		c.Next()

	}
}

func main() {
	r := gin.Default()

	// use cors middleware
	r.Use(CorsMiddleware())
	// 中间件
	r.Use(TimeCost())

	// use gin Recovery  中间件 当有panic 报错的时候返回 500 状态码
	r.Use(gin.Recovery())

	r.GET("/panic", func(c *gin.Context) {
		panic("this is a panic")
	})
	r.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{"hello": "world"})
	})

	// public route
	public := r.Group("/public")

	public.GET("/info", func(c *gin.Context) {
		c.String(200, "public info")
	})

	private := r.Group("/private")

	private.Use(AuthMiddleware())
	private.Use(LoggingMiddleware()) // 先注册 auth middleware 再注册 logging middleware
	private.GET("/info", func(c *gin.Context) {
		c.JSON(200, gin.H{"private info": "leo tel age ..."})
	})
	r.Run(":8080")

}

// cors middleware
func CorsMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		fmt.Println("cors middleware enter ")
		c.Writer.Header().Add("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Add("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Add("Access-Control-Allow-Headers", "Content-Type")
		c.Writer.Header().Add("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE")
		c.Writer.Header().Add("Access-Control-Max-Age", "86400")
		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}
		c.Next()
	}
}
